package com.gaoxk.asclientinterceptor;

import org.apache.cxf.binding.soap.SoapMessage;
import org.apache.cxf.helpers.IOUtils;
import org.apache.cxf.interceptor.Fault;
import org.apache.cxf.interceptor.LoggingMessage;
import org.apache.cxf.io.CachedOutputStream;
import org.apache.cxf.message.Message;
import org.apache.cxf.phase.AbstractPhaseInterceptor;
import org.apache.cxf.phase.Phase;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;

public class ClientOutInterceptor extends AbstractPhaseInterceptor<SoapMessage> {
    private static final Logger logger = LoggerFactory.getLogger(ClientOutInterceptor.class.getName());
    private int limit = 102400;
    /**
     * 客户端申请的token信息
     */
//    private String token;
//
//    public ClientAuthorInterceptor(String token) {
//        // 设置拦截器的时机，在发送请求到服务端之前进行拦截
//        super(Phase.PREPARE_SEND);
//        this.token = token;
//    }
//    public ClientAuthorInterceptor() {
//        // 设置拦截器的时机，在发送请求到服务端之前进行拦截
//        super(Phase.PREPARE_SEND);
//
//    }

//    public ClientInInterceptor(String phase) {
//        super(phase);
//    }
    public ClientOutInterceptor() {
        super(Phase.SEND);
    }

    @Override
    public void handleMessage(SoapMessage message) throws Fault {
        OutputStream os = (OutputStream) message.getContent(OutputStream.class);
        if (os == null) {
            return;
        }
        CachedStream cs = new CachedStream();

        try {



            message.setContent(OutputStream.class, cs);

            message.getInterceptorChain().doIntercept(message);

            CachedOutputStream csnew = (CachedOutputStream) message.getContent(OutputStream.class);
            InputStream in = csnew.getInputStream();

            String xml = IOUtils.toString(in);
            logger.info("====> 作为客户端请求报文 xml=\n[{}]",xml);

//            xml=xml.replace("return", "receiveReturn");//替换成你需要的格式
//
//            System.out.println("replaceAfter"+xml);
            //这里对xml做处理，处理完后同理，写回流中
            IOUtils.copy(new ByteArrayInputStream(xml.getBytes("UTF-8")), os);

            cs.close();
            os.flush();

            message.setContent(OutputStream.class, os);

        } catch (Exception e) {
            logger.error("作为客户端请求出错\n", e);
        }

    }

    private class CachedStream extends CachedOutputStream {

        public CachedStream() {

            super();

        }

        protected void doFlush() throws IOException {

            currentStream.flush();

        }

        protected void doClose() throws IOException {

        }

        protected void onWrite() throws IOException {

        }

    }




    private void logging(SoapMessage message) throws Fault {
        if (message.containsKey(LoggingMessage.ID_KEY)) {
            return;
        }
        String id = (String) message.getExchange().get(LoggingMessage.ID_KEY);
        if (id == null) {
            id = LoggingMessage.nextId();
            message.getExchange().put(LoggingMessage.ID_KEY, id);
        }
        message.put(LoggingMessage.ID_KEY, id);
        LoggingMessage buffer = new LoggingMessage("Inbound Message\n----------------------------", id);

        String encoding = (String) message.get(Message.ENCODING);

        if (encoding != null) {
            buffer.getEncoding().append(encoding);
        }
        String ct = (String) message.get("Content-Type");
        if (ct != null) {
            buffer.getContentType().append(ct);
        }
        Object headers = message.get(Message.PROTOCOL_HEADERS);

        if (headers != null) {
            buffer.getHeader().append(headers);
        }
        String uri = (String) message.get(Message.REQUEST_URI);
        if (uri != null) {
            buffer.getAddress().append(uri);
        }

        InputStream is = (InputStream) message.getContent(InputStream.class);
        if (is != null) {
            CachedOutputStream bos = new CachedOutputStream();
            try {
                IOUtils.copy(is, bos);

                bos.flush();
                is.close();

                message.setContent(InputStream.class, bos.getInputStream());
                if (bos.getTempFile() != null) {
                    buffer.getMessage().append("\nMessage (saved to tmp file):\n");
                    buffer.getMessage().append("Filename: " + bos.getTempFile().getAbsolutePath() + "\n");
                }
                if (bos.size() > this.limit) {
                    buffer.getMessage().append("(message truncated to " + this.limit + " bytes)\n");
                }
                bos.writeCacheTo(buffer.getPayload(), this.limit);

                bos.close();
            } catch (IOException e) {
                throw new Fault(e);
            }
        }
        // 打印日志，保存日志保存这里就可以，可写库或log4j记录日志
        logger.info("请求报文:[{}]",buffer.toString());

    }

    // 出现错误输出错误信息和栈信息
    @Override
    public void handleFault(SoapMessage message) {
        Exception exeption = message.getContent(Exception.class);
        //Logger.error(exeption.getMessage());
        logger.error("出现堆栈错误",exeption);
    }
}
